/*
 * ffssim/src/tools/mkfs_ffssim.c
 *
 * Han Lei <bonben@126.com> (C) 2013.8.5
 */
/*
 * ffssim/src/tools/mkfs_ffssim.c
 *
 * Han Lei <bonben@126.com> (R) 2013.8.9 
 */
#include<stdio.h>
#include<glib.h>
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>

#define ERROR_QUIT -1

static gchar *dev_uri = NULL;
static gint block_size = 0;
static gint chunk_size = 0;
static gint64 max_fs_size = 0;
static gchar *fs_name = "FFSSIM";

static GOptionEntry entries[]= {

    {"filesystem dev_locatin", 'd', 0, G_OPTION_ARG_STRING,&dev_uri,"The dev_location","DEVLOC"},
    {"filesystem block_size",'b',0,G_OPTION_ARG_INT,&block_size, "The block_size","BLOCKSIZE"},
    {"filesystem chunk_size",'c',0,G_OPTION_ARG_INT,&chunk_size, "The chunk_size","CHUNKSIZE"},
    {"filesystem max_size",'m',0,G_OPTION_ARG_INT,&max_fs_size,  "The max FS_size","MAXSIZE"},
};

int main(int argc, char **argv) {
	GError *error = NULL;
	GOptionContext *context=NULL;
	gboolean parse_fact=TRUE;
	
	context=g_option_context_new("- mkfs ffssim");    //As a description
	g_option_context_add_main_entries(context,entries,NULL);
	g_option_context_set_summary(context,"Welcome use FFSSIM!");
	g_option_context_set_help_enabled(context,TRUE);
	parse_fact=g_option_context_parse(context,&argc,&argv,&error);
	if(!parse_fact) {
		g_print("option parsing failed;%s\n",error->message);
		exit(EXIT_FAILURE);
	}

	if(block_size<=0||chunk_size<=0||max_fs_size<=0||block_size%(512)!=0 \
			||chunk_size%(512)!=0||block_size<=chunk_size)
	{
		g_message("block_size or chunk_size set fail! It must be a \
		         multiple of 512B!");
	        exit (EXIT_FAILURE);
	}
	
	g_option_context_free(context);
	g_print("Now value is dev_location: %s block_size: %d chunk_size: %d \
			max_size: %ld\n",dev_uri,block_size,chunk_size,max_fs_size);

	GKeyFile *sb_keyfile=g_key_file_new();
	g_key_file_set_string(sb_keyfile,"METADATA","dev_uri",dev_uri);
	g_key_file_set_integer(sb_keyfile,"METADATA","block_size",block_size);
	g_key_file_set_integer(sb_keyfile,"METADATA","chunk_size",chunk_size);	 
	g_key_file_set_int64(sb_keyfile,"METADATA","max_fs_size",max_fs_size);
	gchar *data=g_key_file_to_data(sb_keyfile,NULL,NULL);
	g_print("key file is %s\n",data);
	
	gchar *sb_file_dirname=g_build_filename(dev_uri,fs_name,NULL);
	g_print("dirname is %s\n",sb_file_dirname);     //create dirname;

	if(!opendir(sb_file_dirname))
	{
		if(ERROR_QUIT==(mkdir(sb_file_dirname,S_IRWXU)))        //create dir
		{
			g_message("Make dir fail\n");
			exit(EXIT_FAILURE);
		}
	} 
	gchar *sb_file_pathname=g_build_filename(sb_file_dirname,"superblock",NULL);
	g_print("filename is %s\n",sb_file_pathname);   //create filename
	
	int fp=open(sb_file_pathname,O_RDWR|O_CREAT);     //create file
	
	if(ERROR_QUIT==fp)
	{
		g_message("Open superblock file fail!\n");
		exit(EXIT_FAILURE);
	}
	
	if((strlen(data)+1)!=write(fp,data,strlen(data)+1)) {
		close(fp);
		g_message("Write file fail\n");
		exit(EXIT_FAILURE);
	} else {
		close(fp);
		g_message("Superblock data write in %s\n",sb_file_pathname);
	}
	return 0;
}
